import asyncio
import re
import time
from settings import AD_MESSAGE, STANDART_DELAY, ACTIVATE_SENDING_MESSAGE, MAX_FAILURES, ACTIVATE_BOTS_MESSAGE, \
    BOT_MESSAGE, CHANNEL_MESSAGE, ACTIVATE_GROUPS_MESSAGE, GROUP_MESSAGE
from Console import console
from loader import Browser
from database import add_group, add_group_account_connection, delete_old_connections
from telethon.tl.functions.channels import JoinChannelRequest, LeaveChannelRequest
from random import randint


async def add_clicking(client, bot_chat, BOT_NAME, http_prx):
    # setting some variables for control
    failures = 0
    url = " "
    pr_url = "some text"
    first_time = True
    skipped = False

    await client.send_message(BOT_NAME, ACTIVATE_SENDING_MESSAGE)
    time.sleep(3)
    while True:
        messages = await client.get_messages(bot_chat, limit=1)
        for message in messages:
            # message.message is a text in current message

            if bool(re.search(AD_MESSAGE, message.message)):
                url = client.get_url_from_button(message)
                console.send_message(url)

                if url == pr_url:

                    time.sleep(15)
                    await message.click(2)  # clicking on a third button in message
                    console.send_message("Skiping")
                    skipped = True

                else:
                    try:
                        Browser.GetUrl(url, use_old_browser=first_time or skipped,
                                       PROXY=http_prx, delay=STANDART_DELAY)
                    except Exception as e:
                        console.send_alert("Something wrong with browser: {}".format(e))
                    if first_time:
                        first_time = False
                    if skipped:
                        skipped = False
                    pr_url = url
                time.sleep(3)



            elif re.search("Sorry, this task is", message.message):
                await client.send_message(BOT_NAME, "/visit")

            elif re.search("Sorry, there are no new ads available.", message.message):
                """
                sleep_for = randint(10, 60)
                console.send_notification("No new ads, sleeping for {} minutes".format(sleep_for))
                time.sleep(60 * sleep_for)
                await client.send_message(BOT_NAME, ACTIVATE_SENDING_MESSAGE)
                """
                return

            else:
                failures += 1
                console.send_notification("Something went wrong, waiting...")

                time.sleep(300)

                await client.send_message(BOT_NAME, ACTIVATE_SENDING_MESSAGE)
                time.sleep(10)
                if failures > MAX_FAILURES:
                    console.send_notification("Exiting because of max failures")

                    return


async def find_and_forward(client, bot_chat, bot_to_activate):
    try:
        await client.send_message(bot_to_activate[0], '/start')
    except Exception as e:
        console.send_alert("Message wasn't sent due to error: {}".format(e))
        return

    time.sleep(2)
    dialogs = await client.get_dialogs()
    bot_to_activate_chat = None
    for dlg in dialogs:

        if dlg.title == bot_to_activate[1]:
            bot_to_activate_chat = dlg

    messages = await client.get_messages(bot_to_activate_chat, limit=1)
    for message in messages:
        if message.text != '/start':
            await client.forward_messages(bot_chat, message)
            time.sleep(2)
    time.sleep(3)

    await client.delete_dialog(bot_to_activate_chat)


async def send_to_bots(client, bot_chat, BOT_NAME, http_prx):
    await client.send_message(BOT_NAME, ACTIVATE_BOTS_MESSAGE)
    time.sleep(3)
    failures = 0
    url = " "
    pr_url = "some text"
    first_time = False
    skipped = False
    bot_to_activate = None

    while True:
        messages = await client.get_messages(bot_chat, limit=1)
        for message in messages:

            if bool(re.search(BOT_MESSAGE, message.message)):
                url = client.get_url_from_button(message)
                console.send_message(url)
                if url == pr_url:
                    await message.click(2)  # clicking on a third button in message
                    console.send_message("Skiping")
                    skipped = True
                    time.sleep(2)

                else:
                    try:
                        bot_to_activate = Browser.GetBotUrl(url, use_old_browser=first_time or skipped,
                                                            PROXY=http_prx, delay=STANDART_DELAY)

                    except Exception as e:
                        console.send_alert("Something wrong with browser: {}".format(e))

                    if first_time:
                        first_time = False
                    if skipped:
                        skipped = False
                    pr_url = url
                time.sleep(3)

            elif re.search("Sorry, this task is", message.message):
                await client.send_message(BOT_NAME, "/bots")

            elif re.search("Sorry, there are no new", message.message):

                return

            else:
                failures += 1
                console.send_message(message.message)
                console.send_alert("Something went wrong, waiting...")

                time.sleep(300)

                await client.send_message(BOT_NAME, ACTIVATE_SENDING_MESSAGE)
                time.sleep(10)
                if failures > MAX_FAILURES:
                    console.send_alert("Exiting because of max failures")

                    return

            if bot_to_activate[0]:
                await find_and_forward(client, bot_chat, bot_to_activate)


async def _join_group(client, bot_chat, group_to_join, message):
    try:

        await client(JoinChannelRequest(channel=group_to_join[1]))
    except Exception as e:
        console.send_critical("Error when joining chanel: {}".format(e))

    time.sleep(3)
    try:
        await message.click(1)
    except Exception as e:
        console.send_alert("Error with clicking on button: {}".format(e))

    time.sleep(1)
    add_group(group_to_join[0], group_to_join[1])
    messages = await client.get_messages(bot_chat, limit=2)
    stay_in_group = 1
    for el in messages:
        if "Success" in el.message:
            pos = el.message.index("at least")

            stay_in_group = int(el.message[pos + 9:el.message[pos + 9:].index(' ') + pos + 9])

    add_group_account_connection(client, group_to_join[1], stay_in_group)
    time.sleep(2)


async def leave_all_old_groups(client):
    groups_to_leave = delete_old_connections(client)
    dialogs = await client.get_dialogs()

    bot_to_activate_chat = None
    for dlg in dialogs:

        if dlg.title in groups_to_leave:
            await client.delete_dialog(dlg)
            time.sleep(1)


async def add_to_the_group(client, bot_chat, BOT_NAME, http_prx):
    await client.send_message(BOT_NAME, ACTIVATE_GROUPS_MESSAGE)
    time.sleep(3)
    failures = 0
    url = " "
    pr_url = "some text"
    first_time = False
    skipped = False
    tries = 0
    group_to_join = [None, None]

    while True:
        console.send_message(tries)
        messages = await client.get_messages(bot_chat, limit=1)
        for message in messages:

            if re.search(CHANNEL_MESSAGE, message.message) or re.search(GROUP_MESSAGE, message.message):
                url = client.get_url_from_button(message)
                console.send_message(url)

                if url != pr_url:
                    tries = 0

                if url == pr_url and tries > 1:
                    await message.click(3)  # clicking on a fourth button in message
                    console.send_message("Skiping")
                    skipped = True
                    tries = 0
                    time.sleep(2)


                else:
                    try:
                        group_to_join = Browser.GetGroupUrl(url, use_old_browser=first_time or skipped,
                                                            PROXY=http_prx, delay=STANDART_DELAY)

                    except Exception as e:
                        console.send_alert("Something wrong with browser: {}".format(e))
                    if first_time:
                        first_time = False

                    if skipped:
                        skipped = False
                    pr_url = url
                    tries += 1
                time.sleep(3)

            elif re.search("Sorry, this task is", message.message):
                await client.send_message(BOT_NAME, "/bots")

            elif re.search("Sorry, there are no new", message.message):

                return
            elif re.search("We cannot find you in the channel", message.message):
                tries = 0 #just retrying

            else:
                failures += 1
                console.send_alert("Something went wrong, waiting...")
                console.send_message(message.message)

                time.sleep(300)

                await client.send_message(BOT_NAME, ACTIVATE_GROUPS_MESSAGE)
                time.sleep(10)
                if failures > MAX_FAILURES:
                    console.send_alert("Exiting because of max failures")

                    return

            if group_to_join[0] and group_to_join[1]:
                await _join_group(client, bot_chat, group_to_join, message)


async def begin(client, bot):
    await client.send_message(bot, ACTIVATE_SENDING_MESSAGE)
    time.sleep(randint(1000, 4000)/1000)
    await client.send_message(bot, ACTIVATE_BOTS_MESSAGE)
    time.sleep(randint(1000, 4000)/1000)
    await client.send_message(bot, ACTIVATE_GROUPS_MESSAGE)
    time.sleep(randint(4000, 8000)/1000)

